package net.pws.oos.security;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.pws.common.util.CollectionUtils;
import net.pws.common.persistence.EntityManager;
import net.pws.common.security.spi.resource.IResource;
import net.pws.common.security.spi.resource.IResourceRepository;
import net.pws.common.security.spi.resource.Resource;
import net.pws.common.security.spi.resource.ResourceDefinitionRepository;
import net.pws.oos.biz.model.User;

import com.thoughtworks.xstream.XStream;

@SuppressWarnings("unchecked")
public class CmsResourceRepository implements IResourceRepository {
    
    public static final XStream xstream = new XStream();
    
    private EntityManager entityManager;
    
    public CmsResourceRepository() {
    }
    
    public void setEntityManager(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    
    public String[] byRole(String roleId) {
        List<String> userIds = entityManager.findList("select u.id from User u left join u.roles r where r.id = ?",
                                                      new Object[] { roleId });
        return (String[]) userIds.toArray(new String[0]);
    }
    
    public List<IResource> getHierarchicalResources(String userId) {
        
        Resource[] resources = ResourceDefinitionRepository.getInstance()
                                                           .getResources();
        Resource[] clonedResources = (Resource[]) xstream.fromXML(xstream.toXML(resources));
        
        User user = (User) entityManager.find(User.class, userId);
        if (User.hasPrivileged(user)) {
            ResourceDefinitionRepository.allowAll(clonedResources);
            return CollectionUtils.asList(clonedResources, IResource.class);
        }
        
        Map<String, Resource> resourceMap = new HashMap<String, Resource>();
        ResourceDefinitionRepository.listToMap(clonedResources, resourceMap);
        
		List<String> allowedResourceIds = (List<String>) entityManager.findList("select distinct p.resourceId from Permission p,User u left join u.roles r where p.role.id = r.id  and u.id = ?",
                                                                                new Object[] { userId });
        for (Iterator<String> iterator = allowedResourceIds.iterator(); iterator.hasNext();) {
            String resourceId = iterator.next();
            Resource resource = resourceMap.get(resourceId);
            if (null != resource) {
                resource.setForbidden(false);
            }
        }
        
        return CollectionUtils.asList(clonedResources, IResource.class);
    }
    
}
